package cn.donting.jme.swing.tab.scene.treenode;

import cn.donting.jme.EditorContent;
import cn.donting.jme.event.SelectEvent;
import cn.donting.jme.event.spatial.SelectSpatialEvent;
import cn.donting.jme.expansion.builder.light.LightAttributeBuilder;
import cn.donting.jme.expansion.builder.mesh.MeshAttributeBuilder;
import cn.donting.jme.utile.IconUtil;
import com.jme3.light.Light;
import com.jme3.light.LightList;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import lombok.Getter;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.List;

import static cn.donting.jme.swing.tab.scene.SceneTreeTab.TREE_NODE_DATA_KEY;

@Getter
public class SpatialTreeNode extends SceneTreeNode {
    private Spatial spatial;
    private JTree jTree;
    private JPopupMenu jPopupMenu;

    public SpatialTreeNode(JTree jTree, Spatial spatial) {
        this.spatial = spatial;
        this.jTree = jTree;
        EditorContent.setObjectData(spatial, TREE_NODE_DATA_KEY, this);
    }


    @Override
    public String toString() {
        return spatial.toString();
    }

    public boolean isNode() {
        return spatial instanceof Node;
    }

    public void openMenu(MouseEvent mouseEvent) {
        if (jPopupMenu != null) {
            jPopupMenu.show(jTree, mouseEvent.getX(), mouseEvent.getY());
            return;
        }
        jPopupMenu = new JPopupMenu();
        JMenuItem refresh = new JMenuItem("刷新");
        refresh.setEnabled(spatial instanceof Node);
        refresh.setIcon(IconUtil.getIcon("icon/refresh.svg"));
        refresh.addActionListener(this::menuRefreshActionEvent);
        jPopupMenu.add(refresh);
        jPopupMenu.add(new JPopupMenu.Separator());


        JMenu newSpa = new JMenu("新建");
        newSpa.setIcon(IconUtil.getIcon("icon/addFile.svg"));
        newSpa.setEnabled(spatial instanceof Node);
        jPopupMenu.add(newSpa);

        JMenuItem newNode = new JMenuItem("节点");
        newNode.setIcon(IconUtil.getIcon("icon/node.svg"));
        newSpa.add(newNode);
        newSpa.add(new JPopupMenu.Separator());
        newNode.addActionListener(e -> EditorContent.runJme(() -> {
            Node node = new Node("new Node");
            Node prent = (Node) spatial;
            prent.attachChild(node);
            EditorContent.runSwing(() -> menuRefreshActionEvent(null));
        }));

        List<MeshAttributeBuilder> meshAttributeBuilders = EditorContent.getIocContainer().getBeansByTypes(MeshAttributeBuilder.class);
        for (MeshAttributeBuilder meshAttributeBuilder : meshAttributeBuilders) {
            JMenuItem newMesh = new JMenuItem(meshAttributeBuilder.getName());
            newMesh.setIcon(meshAttributeBuilder.getIcon(16));
            newSpa.add(newMesh);
        }
        jPopupMenu.add(new JPopupMenu.Separator());

        JMenu newLight = new JMenu("灯光");
        jPopupMenu.add(newLight);

        List<LightAttributeBuilder> lightAttributeBuilders = EditorContent.getIocContainer().getBeansByTypes(LightAttributeBuilder.class);
        for (LightAttributeBuilder lightAttributeBuilder : lightAttributeBuilders) {
            JMenuItem newL = new JMenuItem(lightAttributeBuilder.getName());
            newL.setIcon(lightAttributeBuilder.getIcon(16));
            newLight.add(newL);
        }


        jPopupMenu.add(new JPopupMenu.Separator());
        JMenuItem copy = new JMenuItem("复制");
        copy.setIcon(IconUtil.getIcon("icon/copy.svg"));
        jPopupMenu.add(copy);
        JMenuItem cut = new JMenuItem("剪切");
        cut.setIcon(IconUtil.getIcon("icon/cut.svg"));
        jPopupMenu.add(cut);
        JMenuItem paste = new JMenuItem("粘贴");
        paste.setIcon(IconUtil.getIcon("icon/paste.svg"));
        if (EditorContent.getClipboard() == null || !(EditorContent.getClipboard().getSource() instanceof Spatial)) {
            paste.setEnabled(false);
        }
        jPopupMenu.add(paste);
        JMenuItem delete = new JMenuItem("删除");
        delete.setIcon(IconUtil.getIcon("icon/delete.svg"));
        jPopupMenu.add(delete);

        jPopupMenu.show(jTree, mouseEvent.getX(), mouseEvent.getY());
    }

    @Override
    public SelectEvent getSelectEvent() {
        return new SelectSpatialEvent(jTree,spatial);
    }

    private DefaultTreeModel getTreeModel() {
        return (DefaultTreeModel) jTree.getModel();
    }

    private void menuRefreshActionEvent(ActionEvent actionEvent) {
        removeAllChildren();
        createTreeNode(this);
        getTreeModel().nodeStructureChanged(this);
    }

    public static SpatialTreeNode createTreeNode(JTree jTree, Node node) {
        SpatialTreeNode spatialTreeNode = new SpatialTreeNode(jTree, node);
        createTreeNode(spatialTreeNode);
        return spatialTreeNode;
    }

    private static void createTreeNode(SpatialTreeNode prent) {
        LightList localLightList = prent.spatial.getLocalLightList();
        for (Light light : localLightList) {
            LightTreeNode lightTreeNode = LightTreeNode.createTreeNode(prent.jTree, light, prent.spatial);
            prent.add(lightTreeNode);
        }
        if (prent.spatial instanceof Node) {
            for (Spatial child : ((Node) prent.spatial).getChildren()) {
                SpatialTreeNode childNode = new SpatialTreeNode(prent.jTree, child);
                prent.add(childNode);
                createTreeNode(childNode);
            }
        }
    }

    @Override
    public Icon getIcon(int size) {
        return IconUtil.getIcon(spatial);
    }

    @Override
    public String getName() {
        String name = spatial.getName();
        String objectId = EditorContent.getObjectId(spatial);
        if (name==null) {
            return "-"+objectId;
        }
        return name + objectId;
    }
}